package com.lill.system.web;

import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.lill.common.component.util.PageUtils;
import com.lill.common.component.util.Query;
import com.lill.common.component.util.R;
import com.lill.org.service.ICompanyBranchService;
import com.lill.support.annotation.CurrentUser;
import com.lill.system.constant.SystemConstant;
import com.lill.system.model.SysDomainCompanyModel;
import com.lill.system.model.SysMenuEntity;
import com.lill.system.model.SysUserEntity;
import com.lill.system.service.ICommonRedisService;
import com.lill.system.service.ISysDomainService;
import com.lill.system.service.ISysMenuService;

/**
 * 系统菜单
 *
 * @author lill
 */
@RestController
@RequestMapping("/sys/menu")
public class SysMenuController {
	protected Logger logger = LoggerFactory.getLogger(getClass());
	
    @Autowired
    private ISysMenuService sysMenuService;
    @Autowired
    private ISysDomainService domainService;
    @Lazy
    @Autowired
    private ICompanyBranchService branchService;
    @Autowired
    private ICommonRedisService commonRedisService;

    /**
     * 所有菜单列表
     */
    @RequestMapping("/list")
//    @RequiresPermissions("sys:menu:list")
    public R list(@RequestParam Map<String, Object> params) {
        //查询列表数据
        Query query = new Query(params);
        List<SysMenuEntity> menuList = sysMenuService.queryList(query);
        int total = sysMenuService.queryTotal(query);
        PageUtils pageUtil = new PageUtils(menuList, total, query.getLimit(), query.getPage());

        return R.ok().put("page", pageUtil);
    }

    /**
     * 所有菜单列表
     */
    @RequestMapping("/queryAll")
    public R queryAll(@RequestParam Map<String, Object> params) {
        //查询列表数据
        List<SysMenuEntity> menuList = sysMenuService.queryList(params);

        return R.ok().put("list", menuList);
    }

    /**
     * 选择菜单(添加、修改菜单)
     */
    @RequestMapping("/select")
//    @RequiresPermissions("sys:menu:select")
    public R select() {
        //查询列表数据
        List<SysMenuEntity> menuList = sysMenuService.queryNotButtonList();

        //添加顶级菜单
        SysMenuEntity root = new SysMenuEntity();
        root.setId("0");
        root.setName("一级菜单");
        root.setOpen(true);
        menuList.add(root);

        return R.ok().put("menuList", menuList);
    }

    /**
     * 角色授权菜单
     */
    @RequestMapping("/perms")
//    @RequiresPermissions("sys:menu:perms")
    public R perms(@CurrentUser SysUserEntity curUser) {
        //查询列表数据
        List<SysMenuEntity> menuList = null;

        //只有超级管理员，才能查看所有管理员列表
        if (SystemConstant.SUPER_ADMIN.equals(curUser.getId())) {
            menuList = sysMenuService.queryList(new HashMap<String, Object>());
        } else {
            menuList = sysMenuService.queryUserList(curUser.getId());
        }

        return R.ok().put("menuList", menuList);
    }
    
    /**
     * 角色授权菜单
     */
    @RequestMapping("/menuList")
    //@RequiresPermissions("sys:menu:perms")
    public R menuListByDomain(String domainId) {
    	//查询列表数据
    	List<SysMenuEntity> menuList = sysMenuService.queryMenuList(domainId);
    	
    	return R.ok().put("menuList", menuList);
    }

    /**
     * 菜单信息
     */
    @RequestMapping("/info/{menuId}")
//    @RequiresPermissions("sys:menu:info")
    public R info(@PathVariable("menuId") String menuId) {
        SysMenuEntity menu = sysMenuService.queryObject(menuId);
        return R.ok().put("menu", menu);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
//    @RequiresPermissions("sys:menu:save")
    public R save(@RequestBody SysMenuEntity menu,@CurrentUser SysUserEntity curUser) {
        //数据校验
        verifyForm(menu);

        int result=sysMenuService.save(menu,curUser);
        if(result>0){
    		return R.ok();
        }else{
        	return R.failure();
        }
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
//    @RequiresPermissions("sys:menu:update")
    public R update(@RequestBody SysMenuEntity menu,@CurrentUser SysUserEntity curUser) {
        //数据校验
        verifyForm(menu);

        int result=sysMenuService.update(menu,curUser);
        if(result>0){
    		return R.ok();
        }else{
        	return R.failure();
        }
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
//    @RequiresPermissions("sys:menu:delete")
    public R delete(@RequestBody String[] menuIds,@CurrentUser SysUserEntity curUser) {
    	Map<String, Object> params=new HashMap<String, Object>();
    	params.put("ids", menuIds);
    	params.put("updateUser", curUser.getId());
    	params.put("updateTime", new Date());
        int result=sysMenuService.deleteLogicByMap(params);
        if(result>0){
        	return R.ok();
        }
        return R.failure();
    }

    /**
     * 用户菜单列表
     */
    @RequestMapping("/user")
    public R user(@RequestParam(required = false) String domainId,@RequestParam(required = false) String companyId,
    		@CurrentUser SysUserEntity curUser) {
    	Map<String, Object> mapQuery=new HashMap<String, Object>();
    	if (SystemConstant.SUPER_ADMIN.equals(curUser.getId())) {
    		if(StringUtils.isEmpty(domainId)){
    			mapQuery.put("domainId", SystemConstant.DOMAIN_ID);
    		}else{
    			mapQuery.put("domainId", domainId);
    		}
        } else {
        	mapQuery.put("userId", curUser.getId());
        	mapQuery.put("companyId", curUser.getCompanyId());
    		mapQuery.put("domainId", curUser.getDomainId());
        	if(!StringUtils.isEmpty(domainId)&&!StringUtils.isEmpty(companyId)){
        		Map<String, Object> params=new HashMap<String, Object>();
            	params.put("userId", curUser.getId());
            	params.put("companyId", companyId);
            	params.put("domainId", domainId);
            	List<SysDomainCompanyModel> domainCompanyList=domainService.queryUserAll(params);
            	if (null!=domainCompanyList&&!domainCompanyList.isEmpty()) {
            		mapQuery.put("companyId", companyId);
            		mapQuery.put("domainId", domainId);
            		Object sessionUser= SecurityUtils.getSubject().getPrincipal();
            		try {
    					new PropertyDescriptor("companyId", sessionUser.getClass()).getWriteMethod()
    						.invoke(sessionUser, domainCompanyList.get(0).getCompanyId());
    					
    					new PropertyDescriptor("companyName", sessionUser.getClass()).getWriteMethod()
    						.invoke(sessionUser, domainCompanyList.get(0).getCompanyName());
    					
    					new PropertyDescriptor("departId", sessionUser.getClass()).getWriteMethod()
    						.invoke(sessionUser, domainCompanyList.get(0).getDepartId());
    					
    					new PropertyDescriptor("departName", sessionUser.getClass()).getWriteMethod()
    						.invoke(sessionUser, domainCompanyList.get(0).getDepartName());
    					
    					new PropertyDescriptor("domainId", sessionUser.getClass()).getWriteMethod()
    						.invoke(sessionUser, domainCompanyList.get(0).getId());
    					
    					new PropertyDescriptor("domainName", sessionUser.getClass()).getWriteMethod()
    						.invoke(sessionUser, domainCompanyList.get(0).getDomainName());
    					
    					new PropertyDescriptor("position", sessionUser.getClass()).getWriteMethod()
    						.invoke(sessionUser, domainCompanyList.get(0).getPosition());
    					
    					if(null!=domainCompanyList.get(0).getCompanyType()&&1==domainCompanyList.get(0).getCompanyType()){
    						if(StringUtils.isNotEmpty(domainCompanyList.get(0).getDepartId())){
    							Map<String, Object> branchInfo=branchService.queryUserFirstBranch(domainCompanyList.get(0).getDepartId());
    							if(null!=branchInfo&&!branchInfo.isEmpty()){
    								new PropertyDescriptor("branchId", sessionUser.getClass()).getWriteMethod()
    								.invoke(sessionUser, branchInfo.get("branch_id").toString());
    								new PropertyDescriptor("branchName", sessionUser.getClass()).getWriteMethod()
    								.invoke(sessionUser, branchInfo.get("branch_name")+"");
    								new PropertyDescriptor("branchCode", sessionUser.getClass()).getWriteMethod()
    								.invoke(sessionUser, branchInfo.get("branch_code")+"");
    							}
    						}
    					}else{
    						new PropertyDescriptor("branchId", sessionUser.getClass()).getWriteMethod()
							.invoke(sessionUser, domainCompanyList.get(0).getCompanyId());
							new PropertyDescriptor("branchName", sessionUser.getClass()).getWriteMethod()
							.invoke(sessionUser, domainCompanyList.get(0).getCompanyName());
							new PropertyDescriptor("branchCode", sessionUser.getClass()).getWriteMethod()
							.invoke(sessionUser, domainCompanyList.get(0).getCompanyCode());
    					}
    				} catch (Exception e) {
    					logger.error(e.getMessage(), e);
    				}
    			
            		List<SysMenuEntity> changeMenuList = sysMenuService.queryCurUserMenuList(params);
            		if(null!=changeMenuList&&!changeMenuList.isEmpty()){
            			List<String> permsList = new ArrayList<String>();
            			for (SysMenuEntity menu : changeMenuList) {
            				if(StringUtils.isNotEmpty(menu.getPerms())){
            					String[] perms=menu.getPerms().split(",");
            					for (String permVal : perms) {
            						permsList.add(permVal);
            					}
            				}
            			}
            			commonRedisService.setKeyStringValueListStringWithTime(SystemConstant.SYS_PERMS_KEY+curUser.getId(), permsList, SystemConstant.SYS_CACHE_SESSION_TIME, TimeUnit.SECONDS);
            		}
            	}
        	}
        }
    	List<SysMenuEntity> menuList = sysMenuService.getUserMenuList(mapQuery);
        return R.ok().put("menuList", menuList);
    }

    /**
     * 验证参数是否正确
     */
    private void verifyForm(SysMenuEntity menu) {
        if (StringUtils.isBlank(menu.getName())) {
            throw new RuntimeException("菜单名称不能为空");
        }

        if (menu.getParentId() == null) {
            throw new RuntimeException("上级菜单不能为空");
        }

        //菜单
        if (menu.getType() == 1) {
            if (StringUtils.isBlank(menu.getUrl())) {
                throw new RuntimeException("菜单URL不能为空");
            }
        }

        //上级菜单类型
        int parentType = 0;
        if (StringUtils.isNotEmpty(menu.getParentId()) && !"0".equals(menu.getParentId())) {
            SysMenuEntity parentMenu = sysMenuService.queryObject(menu.getParentId());
            parentType = parentMenu.getType();
        }

        //目录、菜单
        if (menu.getType() == 0 ||
                menu.getType() == 1) {
            if (parentType != 0) {
                throw new RuntimeException("上级菜单只能为目录类型");
            }
            return;
        }

        //按钮
        if (menu.getType() == 2) {
            if (parentType != 1) {
                throw new RuntimeException("上级菜单只能为菜单类型");
            }
            return;
        }
    }
}
